package sk.naive.talker.server;

import sk.naive.talker.*;
import sk.naive.talker.props.PropertyStoreException;
import sk.naive.talker.persistence.PersistenceException;
import sk.naive.talker.util.Utils;

import java.util.*;
import java.rmi.RemoteException;

/**
 * @author <a href="mailto:virgo@naive.deepblue.sk">Richard "Virgo" Richter</a>
 * @version $Revision: 1.14 $ $Date: 2005/02/20 13:08:17 $
 */
public class BoardRegistry
	implements BoardFinder {
	private Map<Integer, Board> idBoard;
	private Map<String, Board> nameBoard;
	private Set<String> boardNames;
	private BoardFactory factory;

	public BoardRegistry(BoardFactory bf) {
		nameBoard = new HashMap<String, Board>();
		idBoard = new HashMap<Integer, Board>();
		this.boardNames = new TreeSet<String>();
		factory = bf;
	}

	/**
	 * @param name
	 * @return created board or null if board with specified name exists
	 * @throws PersistenceException
	 */
	public Board createBoard(String name) throws PersistenceException {
		name = Utils.normalize(name);
		Board brd = null;
		if (!boardNames.contains(name)) {
			try {
				brd = factory.createBoard(name);
			} catch (RemoteException e) {
				Utils.unexpectedExceptionWarning(e);
			}
			addBoard(brd);
		}
		return brd;
	}

	public void destroy(Board brd) throws PersistenceException {
		brd.clear();
		factory.remove(brd);
		removeBoard(brd);
	}

	public void rename(Board brd, String newName) throws PropertyStoreException {
		String oldName = brd.getName();
		brd.set(Board.BPROP_NAME, newName);
		boardNames.remove(oldName);
		boardNames.add(newName);
		nameBoard.remove(oldName);
		nameBoard.put(newName, brd);
	}

	public Collection boards() {
		return idBoard.values();
	}

	public void addBoard(Board board) {
		boardNames.add(board.getName());
		nameBoard.put(board.getName(), board);
		idBoard.put(board.getId(), board);
	}

	public void removeBoard(Board board) {
		boardNames.remove(board.getName());
		nameBoard.remove(board.getName());
		idBoard.remove(board.getId());
	}

	public Board findBoardByName(String name) {
		name = Utils.normalize(name);
		String foundName = Utils.findFirstInCollection(name, boardNames, false);
		if (foundName == null) {
			return null;
		}
		return (Board) nameBoard.get(foundName);
	}
}
